package com.lc.service.impl;

import com.lc.entity.Food;
import com.lc.mapper.FoodMapper;
import com.lc.service.FoodService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;

/**
 * Author:LC
 * Version:jdk-8u301
 * Date: 2022/7/4 10:02
 *
 * @CacheConfig : 可用于定义类中方法的公共缓存配置
 *      cacheNames, keyGenerator, cacheManager, cacheResolver
 *
 */
@CacheConfig(cacheNames = "food", keyGenerator = "myKeyGenerator")
@Service
public class FoodServiceImpl implements FoodService {

    @Autowired
    private FoodMapper foodMapper;

    /**
     *
     * 将方法的运行结果进行缓存，以后需要相同数据，可直接从缓存中拿
     *
     * CacheManager管理多个Cache组件，对缓存结果进行CRUD的是Cache组件，每一个缓存组件有自己唯一的名字
     * @Cacheable 的属性：
     *      1.cacheNames/value:指定缓存组件的名字；
     *      2.key:缓存数据使用key，默认是使用方法参数的值，
     *          (1)方法的返回值；  (2)SpEL：#id, #p, #root.args[0]
     *        keyGenerator:key生成器，可以自己指定生成key
     *        keyGenerator/key二选一
     *       3.cacheManager：指定缓存管理器；  cacheResolver：获取指定解析器；
     *       4.condition：制定符合条件的情况下才缓存；
     *       5.unless:否定缓存，若unless条件结果为true，则返回值不进行缓存，也可以获取方法的返回结果进行判断
     *       6.sync:是否使用异步模式
     *
     * 执行步骤：
     *      先在缓存中创建key，在存入缓存数据。所以key不可以用result进行赋值
     */
    @Override
    @Cacheable(cacheNames = "food", keyGenerator = "myKeyGenerator")
    //key = "#root.methodName + '[' + #id + ']'
    public Food findFoodById(Integer id) {
        System.out.println("查询工号为：" + id + "的员工");
        return foodMapper.selectFoodById(id);
    }


    /**
     * @CachePut :即调用方法，又更新缓存数据；
     *
     * 执行步骤：
     *      先执行方法体，在改变缓存，所以可以使用result对key的值进行改变
     */
    @Override
    @CachePut(value = "food", key = "#food.id")
    public int modifyFoodData(Food food) {
        System.out.println("update:" + food);
        return foodMapper.updateFoodData(food);
    }


    /**
     * @CacheEvict : 缓存清除
     *      key: 指定清除的数据
     *      allEntries: 清楚缓存中全部的数据，默认为false；
     *      beforeInvocation: 表示在方法执行之后在执行清空缓存，默认是false。若在方法执行期间遇到异常，则无法清空缓存；
     */

    @CacheEvict(value = "food", key = "#id", allEntries = true)
    public void delFood(Integer id){
    }


    /**
     * @Caching : 定义复杂的缓存规则
     */
    @Caching(
        cacheable = {@Cacheable(value = "food", key = "#name")},
        put = {@CachePut(value = "food", key = "#result.id"),
                @CachePut(value = "food", key = "#result.name")}
    )
    public Food getFoodByName(String name){
        return foodMapper.selectFoodByName(name);
    }
}
